#include "BlockQueue.hpp"
#include <ctime>
#include "task.hpp"

// void *consumer(void *args)
// {
//     BlockQueue<int> *bqp = static_cast<BlockQueue<int> *>(args);
//     while (true)
//     {
//         int data = bqp->pop();
//         cout << "consumer 消费数据完成：" << data << endl;
//     }
// }

// void *productor(void *args)
// {
//     BlockQueue<int> *bqp = static_cast<BlockQueue<int> *>(args);
//     while (true)
//     {
//         // 1.制作数据
//         int data = rand() % 10;
//         // 2.生产数据
//         bqp->push(data);
//         cout << "proctor 生产数据完成:" << data << endl;
//         sleep(1);
//     }
// }


// 并发，并不是在临界区中并发（一般），而是生产前(before blockqueue),消费后(after blockqueue)对应的并发

void *consumer(void *args)
{
    BlockQueue<Task> *bqp = static_cast<BlockQueue<Task> *>(args);
    while (true)
    {
        Task t = bqp->pop();
        int result = t(); // 调用仿函数处理任务
        int one, two;
        char op;
        t.get(&one, &two, &op);
        cout << "consumer[" << pthread_self() << "]" << (unsigned long)time(nullptr)
             << " 消费了一个任务：" << one << op << two << "=" << result << endl;
    }
}

const std::string ops = "+-*/%";
void *productor(void *args)
{
    BlockQueue<Task> *bqp = static_cast<BlockQueue<Task> *>(args);
    while (true)
    {
        // 1.制作任务
        int one = rand() % 20;
        int two = rand() % 20;
        char op = ops[rand() % ops.size()];
        Task t(one, two, op);
        // 2.生产数据
        bqp->push(t);
        cout << "producer[" << pthread_self() << "]" << (unsigned long)time(nullptr)
             << " 生产了一个任务：" << one << op << two << "=" << endl;
        sleep(1);
    }
}

int main()
{
    // BlockQueue<int> bq;
    // bq.push(10);
    // int a=bq.pop();

    // cout<<a<<endl;

    srand((unsigned long)time(nullptr) ^ getpid());
    // 既然可以使用int类型的数据，那也可以使用自己定义的类型，包括任务
    // BlockQueue<int> bq;
    BlockQueue<Task> bq;

    pthread_t c, p;
    pthread_create(&c, nullptr, consumer, &bq);
    pthread_create(&p, nullptr, productor, &bq);

    pthread_join(c, nullptr);
    pthread_join(p, nullptr);
    return 0;
}